package app

import (
	"context"
	"fmt"
	"log"
	"net/http"
	consts "qrsj-collect/backend/const"
	"qrsj-collect/backend/dao"
	"qrsj-collect/backend/models"
	"qrsj-collect/backend/utils"
	"sync"
	"time"

	jsoniter "github.com/json-iterator/go"
	"github.com/wailsapp/wails/v2/pkg/runtime"
)

type ServerApp struct {
	ctx       context.Context
	json      jsoniter.API
	tempToken string

	cancelFunc context.CancelFunc
	mu         sync.Mutex
}

func NewServerApp() *ServerApp {
	return &ServerApp{}
}

func (a *ServerApp) Startup(ctx context.Context) {
	var wg sync.WaitGroup
	a.ctx = ctx
	a.json = jsoniter.ConfigCompatibleWithStandardLibrary
	wg.Add(1)
	go func() {
		defer wg.Done()
		if err := dao.InitMysql(); err != nil {
			log.Printf("Error initializing MySQL: %v", err)
			return
		}
		if err := dao.Ping(); err != nil {
			runtime.EventsEmit(a.ctx, "errorMsg", "服务端连接失败")
		}
	}()
	wg.Wait()
}

func (a *ServerApp) Shutdown(ctx context.Context) {
	a.ServerStopOnlineStatus()
	a.ServerSetOnlineStates(false)
	dao.CloseMysql()
}

func (a *ServerApp) ServerGetAppInfo() map[string]interface{} {
	var app models.App
	dao.DB.Model(&models.App{}).First(&app, 1)
	if app.ID == 0 {
		app.DownloadUrl = consts.DownloadUrl
		app.Pwd = consts.Pwd
		app.FileIndex = consts.FileIndex
		app.GroupChatUrl = consts.GroupChatUrl
	}
	return map[string]interface{}{"code": http.StatusOK, "msg": "应用初始化成功", "data": app}
}

// 注册
func (a *ServerApp) ServerRegister(username, email, password string) map[string]interface{} {
	if err := dao.CheckDBConnection(); err != nil {
		return map[string]interface{}{"code": http.StatusInternalServerError, "msg": err.Error()}
	}
	var user models.User
	dao.DB.Where("username = ?", username).First(&user)
	if user.ID != 0 {
		return map[string]interface{}{"code": http.StatusBadRequest, "msg": "用户已存在"}
	}
	// dao.DB.Where("email = ?", email).First(&user)
	// if user.ID != 0 {
	// 	return map[string]interface{}{"code": http.StatusBadRequest, "msg": "邮箱已存在"}
	// }
	user.Username = username
	password, _ = utils.HashPassword(password)
	user.Password = password
	user.Email = email
	// // nickname默认为用户+username的后四位
	user.Nickname = `用户` + username
	initTime := time.Date(1970, 1, 1, 0, 0, 0, 0, time.Local)
	user.VipInfo.ExpireTime = &initTime
	if len(username) > 4 {
		user.Nickname = `用户` + username[len(username)-4:]
	}
	if err := dao.DB.Create(&user).Error; err != nil {
		return map[string]interface{}{"code": http.StatusInternalServerError, "msg": "注册失败"}
	}
	return map[string]interface{}{"code": http.StatusOK, "msg": "注册成功"}
}

// 登录
func (a *ServerApp) ServerLogin(username, password string) map[string]interface{} {
	if err := dao.CheckDBConnection(); err != nil {
		return map[string]interface{}{"code": http.StatusInternalServerError, "msg": err.Error()}
	}
	var user models.User
	dao.DB.Where("username = ?", username).First(&user)
	if user.ID == 0 {
		return map[string]interface{}{"code": http.StatusBadRequest, "msg": "账号或密码错误"}
	}
	if !utils.CheckPasswordHash(password, user.Password) {
		return map[string]interface{}{"code": http.StatusBadRequest, "msg": "账号或密码错误"}
	}
	token := utils.GenerateToken(user.ID, username)
	go func() {
		var loginRecord models.LoginRecord
		// loginRecord.UserID = user.ID
		loginRecord.LoginTime = time.Now()
		ip, address := utils.GetIpAndAddress()
		fmt.Println(ip, address)
		loginRecord.Ip = ip
		loginRecord.Address = address
		// 关联关系追加
		dao.DB.Model(&user).Association("LoginRecord").Append(&loginRecord)
	}()
	return map[string]interface{}{"code": http.StatusOK, "msg": "登录成功", "token": token}
}

// 登出
func (a *ServerApp) ServerLogout(token string) map[string]interface{} {
	a.ServerStopOnlineStatus()
	a.ServerSetOnlineStates(false)
	utils.InvalidateToken(token)
	return map[string]interface{}{"code": http.StatusOK, "msg": "登出成功"}
}

// 找回密码
func (a *ServerApp) ServerFindPassword(username, email, password string) map[string]interface{} {
	if err := dao.CheckDBConnection(); err != nil {
		return map[string]interface{}{"code": http.StatusInternalServerError, "msg": err.Error()}
	}
	var user models.User
	dao.DB.Where("username = ?", username).First(&user)
	if user.ID == 0 {
		return map[string]interface{}{"code": http.StatusBadRequest, "msg": "用户不存在"}
	}
	if user.Email != email {
		return map[string]interface{}{"code": http.StatusBadRequest, "msg": "邮箱错误"}
	}
	password, _ = utils.HashPassword(password)
	// user.Password = password
	if err := dao.DB.Model(&user).Update("password", password).Error; err != nil {
		return map[string]interface{}{"code": http.StatusInternalServerError, "msg": "修改密码失败"}
	}
	return map[string]interface{}{"code": http.StatusOK, "msg": "修改密码成功"}
}

// 用户信息
func (a *ServerApp) ServerGetUserInfo(token string) map[string]interface{} {
	if err := dao.CheckDBConnection(); err != nil {
		return map[string]interface{}{"code": http.StatusInternalServerError, "msg": err.Error()}
	}
	a.tempToken = token
	var claims *utils.Claims
	claims, _ = utils.ValidateToken(token)
	if claims == nil {
		return map[string]interface{}{"code": http.StatusUnauthorized, "msg": "登录已过期"}
	}
	var user models.User
	dao.DB.Where("username = ?", claims.Username).First(&user)
	fmt.Println(user)
	if user.ID == 0 {
		return map[string]interface{}{"code": http.StatusBadRequest, "msg": "用户不存在"}
	}
	return map[string]interface{}{"code": http.StatusOK, "msg": "获取用户信息成功", "data": user}
}

// 登录记录
func (a *ServerApp) ServerGetLoginRecord(token string) map[string]interface{} {
	if err := dao.CheckDBConnection(); err != nil {
		return map[string]interface{}{"code": http.StatusInternalServerError, "msg": err.Error()}
	}
	var claims *utils.Claims
	claims, _ = utils.ValidateToken(token)
	if claims == nil {
		return map[string]interface{}{"code": http.StatusUnauthorized, "msg": "登录已过期"}
	}
	var user models.User
	dao.DB.Where("username = ?", claims.Username).First(&user)
	if user.ID == 0 {
		return map[string]interface{}{"code": http.StatusBadRequest, "msg": "用户不存在"}
	}
	var loginRecords []models.LoginRecord
	dao.DB.Model(&user).Association("LoginRecord").Find(&loginRecords)
	return map[string]interface{}{"code": http.StatusOK, "msg": "获取登录记录成功", "data": loginRecords}
}

// 停止统计在线状态
func (a *ServerApp) ServerStopOnlineStatus() {
	a.mu.Lock()
	defer a.mu.Unlock()
	if a.cancelFunc != nil {
		a.cancelFunc()
		a.cancelFunc = nil
	}
	if a.tempToken == "" {
		return
	}
	claims, _ := utils.ValidateToken(a.tempToken)
	if claims == nil {
		return
	}
	var user models.User
	dao.DB.Where("username = ?", claims.Username).First(&user)
	if user.ID == 0 {
		return
	}
	if user.IsOnline {
		dao.DB.Model(&user).Update("is_online", false)
	}
	fmt.Printf("%s -> 已离线\n", user.Nickname)
}

// 设置在线状态
func (a *ServerApp) ServerSetOnlineStates(state bool) {
	if a.tempToken == "" {
		return
	}
	claims, _ := utils.ValidateToken(a.tempToken)
	if claims == nil {
		return
	}
	var user models.User
	dao.DB.Where("username = ?", claims.Username).First(&user)
	if user.ID == 0 {
		return
	}
	if !user.IsOnline {
		dao.DB.Model(&user).Update("is_online", true)
	}
	if state {
		fmt.Printf("%s -> 在线中\n", user.Nickname)
	} else {
		fmt.Printf("%s -> 已离线\n", user.Nickname)
	}
}

// 获取菜单列表
func (a *ServerApp) ServerGetMenuList() map[string]interface{} {
	if err := dao.CheckDBConnection(); err != nil {
		return map[string]interface{}{"code": http.StatusInternalServerError, "msg": err.Error()}
	}
	var menus []models.Menu
	dao.DB.Find(&menus)
	if len(menus) == 0 {
		return map[string]interface{}{"code": http.StatusInternalServerError, "msg": "菜单数据不存在"}
	}
	return map[string]interface{}{"code": http.StatusOK, "msg": "获取菜单列表成功", "data": menus}
}
